<?php

namespace App\Http\Controllers\Api;

use App\Constant;
use App\Enums\DivideStatus;
use App\Enums\OrderStatus;
use App\Enums\PaymentStatus;
use App\Enums\Payway;
use App\Enums\ProductStatus;
use App\Enums\WalletStatus;
use App\Events\OrderPaid;
use App\Models\MergeOrder;
use App\Models\MergeOrderItem;
use App\Models\OrderPayment;
use App\Models\UserWallet;
use Arr;
use Carbon\Carbon;

class SdPayController
{
    public function payNotify()
    {
        $data = json_decode(urldecode(request()->data), true);
        \Log::channel(Constant::LOG_CHANNEL_SDPAY)->info('PAY_NOTIFY', $data);
        //云账户C2C订单
        if (Arr::has($data, ['transType', 'respCode'])) {
            $respCode = Arr::get($data, 'respCode');
            if ('00000' !== $respCode) {
                return 'respCode=000000';
            }
            $outOrderNo = Arr::get($data, 'orderNo');
            if (\Str::startsWith($outOrderNo, 'M')) {
                $this->processMergeOrder($outOrderNo, $data);
            } else {
                //普通订单
                $this->processNormalOrder($outOrderNo, $data);
            }

            return 'respCode=000000';
        }

        //云账户C2B和快捷支付订单
        $respCode = \Arr::get($data, 'head.respCode');
        if ('000000' !== $respCode) {
            return 'respCode=000000';
        }
        $orderNo = \Arr::get($data, 'body.orderCode');
        $merchantNo = \Arr::get($data, 'body.mid');
        if (\Str::startsWith($orderNo, 'WALLET_')) {
            //钱包订单
            $walletUserNo = substr($orderNo, 7, 11);
            UserWallet::query()->where('merchant_no', $merchantNo)
                ->where('wallet_user_no', $walletUserNo)
                ->update([
                    'status' => WalletStatus::PAID,
                ]);
        } else {
            //普通订单
            $outOrderNo = Arr::get($data, 'body.orderCode');
            $payment = OrderPayment::query()->where('out_order_no', $outOrderNo)->first();
            if ($payment->pay_status->is(PaymentStatus::PAYING)) {
                \DB::transaction(function () use ($data, $payment) {
                    $merchantFee = Arr::get($data, 'body.midFee');
                    $payment->pay_status = PaymentStatus::FINISHED;
                    $payment->pay_time = Carbon::parse(Arr::get($data, 'body.payTime'));
                    $payment->receive_amount = $payment->pay_amount - $merchantFee;
                    $payment->divide_status = DivideStatus::NOT_SUPPORT;
                    $payment->save();

                    $order = $payment->order;
                    if ($order->order_status->is(OrderStatus::NOT_PAY())) {
                        $order->order_status = OrderStatus::PAID;
                        $order->save();

                        //转售订单标记为停止发行
                        $product = $order->product;
                        if ($order->is_resale) {
                            $product->status = ProductStatus::STOP;
                            $product->save();
                        }

                        OrderPaid::dispatch($order);
                    }
                });
            }
        }

        return 'respCode=000000';
    }

    public function walletNotify()
    {
        $data = json_decode(urldecode(request()->data), true);
        \Log::channel(Constant::LOG_CHANNEL_SDPAY)->info('WALLET_NOTIFY', $data);
        $bizType = \Arr::get($data, 'bizType');
        $mid = \Arr::get($data, 'mid');
        $userNo = \Arr::get($data, 'bizUserNo');
        $code = \Arr::get($data, 'respCode');
        if ('SIGN_PROTOCOL' === $bizType && '0000' == $code) {
            UserWallet::query()
                ->where('merchant_no', $mid)
                ->where('wallet_user_no', $userNo)->update([
                    'status' => WalletStatus::OPENED,
                ]);
        }

        return 'respCode=000000';
    }

    private function processNormalOrder($outOrderNo, $data)
    {
        /** @var OrderPayment $payment */
        $payment = OrderPayment::query()->where('out_order_no', $outOrderNo)->first();
        if ($payment->pay_status->is(PaymentStatus::PAYING)) {
            \DB::transaction(function () use ($data, $payment) {
                $merchantFee = toFen(Arr::get($data, 'feeAmt', 0));
                $payment->pay_status = PaymentStatus::FINISHED;
                $payment->pay_time = Carbon::parse(Arr::get($data, 'respTime'));
                $payment->receive_amount = $payment->pay_amount - $merchantFee;
                $payment->platform_receive_amount = 0;
                $payment->agent_receive_amount = toFen(Arr::get($data, 'userFeeAmt', 0));
                $payment->user_receive_amount = $payment->receive_amount - $payment->agent_receive_amount;
                $payment->divide_status = DivideStatus::DIVIDED;
                $payment->save();

                $order = $payment->order;
                if ($order->order_status->is(OrderStatus::NOT_PAY())) {
                    $order->order_status = OrderStatus::PAID;
                    $order->save();

                    //转售订单标记为停止发行
                    $product = $order->product;
                    if ($order->is_resale) {
                        $product->status = ProductStatus::STOP;
                        $product->save();
                    }

                    OrderPaid::dispatch($order);
                }
            });
        }
    }

    private function processMergeOrder($outOrderNo, $data)
    {
        /** @var MergeOrder $mergeOrder */
        $mergeOrder = MergeOrder::query()->where('order_no', $outOrderNo)->first();
        if ($mergeOrder->status->isNot(OrderStatus::NOT_PAY)) {
            return 'respCode=000000';
        }
        $mergeOrderItems = $mergeOrder->items()->with(['order.product', 'order.payment'])->get();
        /** @var MergeOrderItem $item */
        foreach ($mergeOrderItems as $item) {
            $order = $item->order;
            //创建payment数据
            $payment = $order->payment;
            if (!$payment) {
                $payment = new OrderPayment();
                $payment->order_id = $item->order_id;
                $payment->merchant_no = '-';
                $payment->out_order_no = $outOrderNo . '_' . $item->order_id;
                $payment->pay_amount = $order->order_amount;
                $payment->pay_way = Payway::UNION_PAY;
                $payment->pay_status = PaymentStatus::FINISHED;
                $payment->pay_time = Carbon::parse(Arr::get($data, 'respTime'));
                $payment->receive_amount = $item->order_amount;
                $payment->platform_receive_amount = 0;
                $payment->agent_receive_amount = $item->service_fee;
                $payment->user_receive_amount = $item->order_amount - $item->service_fee;
                $payment->divide_status = DivideStatus::DIVIDED;
                $payment->save();
            }
            if ($order->order_status->is(OrderStatus::MERGE_PAYING)) {
                $order->order_status = OrderStatus::PAID;
                $order->save();
                //转售商品标记为停止发行
                $product = $order->product;
                if ($order->is_resale) {
                    $product->status = ProductStatus::STOP;
                    $product->save();
                }
                OrderPaid::dispatch($order);
            }
        }
    }
}
